package view.actionListeners;

import java.awt.Color;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;

import javax.swing.JButton;

import utils.ActivateButton;
import view.DisplayManager;
import view.displayManagers.GameDisplayTool.ClickedPiece;
import controller.GameManager;
import controller.HumanControlledGame;
import controller.Move;

/**
 * Class implements an action listener for board button, used in single player game mode
 */
public class SinglePlayerListener extends TwoPlayersListener {

	// member
	private Timer timer; // used to delay refreshing the display after computer's turn
	
	// private methods
	
	/**
	 * Uses game manager to run a single turn of the computer.
	 * This task is scheduled in order to delay refreshing the display 
	 */
	private void computerTurn() {
		
		// the task to be scheduled
		TimerTask timerTask = new TimerTask() {
			
			@Override
			public void run() {
				
				// make computer move
				Move chosenMove = gameManager.makeMoveComputer();
				
				// update changed positions on board 
				lastToBeClicked.getMoveList().clear();
				lastToBeClicked.getMoveList().add(chosenMove.getSource());
				lastToBeClicked.getMoveList().add(chosenMove.getDestination());
				
				// refresh board display
				displayManager.refreshBoardDisplay();
			
				// move made, check if Checkmate
				if (gameManager.isCheckmate()) {
					
					// TODO DEBUG!!!
					((GameManager)gameManager).logger.close();
					//
					
					// end game
					displayManager.gameOver("You have lost, checkmate!"); 
					return;					
				 } 
				
				// move made, check if Stalemate
				if (gameManager.isStalemate()) {

					// TODO DEBUG!!!
					((GameManager)gameManager).logger.close();
					//

					// end game
					displayManager.gameOver("You have lost, stalemate!"); 
					return;
				}
				
				// game not over, check if attacked King is threatened
				if (gameManager.isCheck()) {
					// notify user
					displayManager.notifyCheck();					 
				}
				
				// enable board buttons
				buttonActivator.activateSystem();
			}
		};
		
//		timer.schedule(timerTask, 2000); // TODO use const // TODO used to be activated
		timer.schedule(timerTask, 1000); // TODO use const
	}
	
	// public methods
	
	/**
	 * Constructor- creates a new single-player-listener object
	 * @param boardSize- game board's size
	 * @param mark- color to mark reachable positions
	 * @param displayManager- used to manage board display
	 * @param gameManager- reference to game manager
	 * @param lastToBeClicked- holds data about last-to-be-clicked button
	 * @param boardButtons- board buttons
	 * @param buttonActivator- used to switch board buttons on or off
	 */
//	public SinglePlayerListener(int boardSize, Color mark, DisplayManager displayManager, Controller gameManager, ClickedPiece lastToBeClicked, List<JButton> boardButtons, ActivateButton buttonActivator) {
	public SinglePlayerListener(int boardSize, Color mark, DisplayManager displayManager, HumanControlledGame gameManager, ClickedPiece lastToBeClicked, List<JButton> boardButtons, ActivateButton buttonActivator) { // TODO DEBUG!!!
		
		// initialize object using base class's constructor
		super(boardSize, mark, displayManager, gameManager, lastToBeClicked, boardButtons, buttonActivator);
		
		// allocate a new timer
		timer = new Timer();
	}
	
	/**
	 * When button is clicked, asks game manager for list of reachable positions of piece at clicked button.
	 * If list is empty, nothing is done.
	 * Otherwise, last-to-be-clicked button is updated to this clicked button and piece's reachable positions are marked.
	 * If clicked position is included in last-to-be-clicked button's moves, than piece at last-to-be-clicked button is moved
	 * to the clicked position
	 */
	@Override
	public void actionPerformed(ActionEvent event) {
		
		// check if buttons are activated
		if (!buttonActivator.isActivated()) {
			
			// not activated, do nothing
			return;
		}
		
		// get clicked button position on board
		Point clickedPosition = getButtonPosition(event); 
		
		// check if should make move
		if (makeMove(clickedPosition)) {

			// move made, check if Checkmate
			if (gameManager.isCheckmate()) {				
				// game is over
				displayManager.gameOver("Well done, checkmate!");
				return;				
			} 
			
			// move made, check if Stalemate
			if (gameManager.isStalemate()) {				
				// game is over
				displayManager.gameOver("Well done, stalemate!");
				return;				
			}
			
			// game not over, check if attacked King is threatened
			if (gameManager.isCheck()) {				
				// notify user
				displayManager.notifyCheck();
			}
			
			// disable board buttons
			buttonActivator.disableSystem();

			// player has moved, now perform computer's turn
			computerTurn();
			return;			
			
		} else {
			// no move to make
			findMoves(clickedPosition.x, clickedPosition.y);
		}
	}
}